package za.org.meraka.cair.ontorepair;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Iterator;
import java.util.Collections;
import java.awt.Color;


import org.semanticweb.owlapi.apibinding.OWLManager;
import org.protege.editor.owl.model.OWLModelManager;
import org.protege.editor.owl.ui.renderer.OWLModelManagerEntityRenderer;
import org.protege.editor.owl.ui.renderer.OWLObjectRenderer;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.reasoner.ConsoleProgressMonitor;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerConfiguration;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import org.semanticweb.owlapi.reasoner.SimpleConfiguration;
import org.semanticweb.owlapi.util.*;
//import org.semanticweb.owlapi.inference.*;

public class AxiomPrinter {
			
	private OWLOntology ontology;
	private OWLModelManagerEntityRenderer entityRenderer;
	private OWLObjectRenderer objectRenderer;
	private OWLReasoner reasoner;
	private OWLOntologyManager manager;
	//private ResultPane result;
	
	public AxiomPrinter(){}
	
	public AxiomPrinter(OWLModelManager model) throws OWLOntologyCreationException{
		//ontology = ont;
		//Setup renderer which enables one to display axioms and classes
		//entityRenderer = model.getOWLEntityRenderer();
		objectRenderer = model.getOWLObjectRenderer();
		manager = OWLManager.createOWLOntologyManager();

//		OWLOntology ont = manager.createOntology(model.getActiveOntology().getOntologyID());		
//		OWLReasonerFactory reasonerFactory = null;
//		ConsoleProgressMonitor progressMonitor = new ConsoleProgressMonitor();
//		OWLReasonerConfiguration config = new SimpleConfiguration(progressMonitor);
		reasoner = model.getReasoner();//createReasoner(ont, config);
		
		//reasoner = model.getOWLReasonerManager().createReasoner(manager);
	}
	
	public AxiomPrinter(OWLModelManagerEntityRenderer entRen, OWLObjectRenderer objRen){
		entityRenderer = entRen;
		objectRenderer = objRen;
	}
		
	//Returns string representation of all asserted axioms in the ontology
	public String getAllAxioms(){		
		String result = "";
		Set<OWLAxiom> set = ontology.getAxioms();
		result += "Total Axioms: "; result += set.size();result += "\n\n";		
		Iterator<OWLAxiom> axiomIterator = set.iterator();
    	while (axiomIterator.hasNext()){
    		result += objectRenderer.render(axiomIterator.next());
    		result += "\n";    		
    	}
    	result += "\n";		
    	return result;
	}

	//Returns string representation of all logical asserted axioms in the ontology
	public String getLogicalAxioms(){
		String result = "";
		Set<OWLLogicalAxiom> set = ontology.getLogicalAxioms();
		result += "Logical Axioms: "; result += set.size();result += "\n\n";
		Iterator<OWLLogicalAxiom> axiomIterator = set.iterator();
    	while (axiomIterator.hasNext()){
    		result += objectRenderer.render(axiomIterator.next());
    		result += "\n";    		
    	}
    	result += "\n";		
    	return result;
	}				
	
	//Returns actual inferred axioms from an ontology.
//	public Set<OWLAxiom> getInferredAxioms2() throws OWLException {
//		reasoner.loadOntologies(Collections.singleton(ontology));
//		reasoner.classify();				
//		List<InferredAxiomGenerator<? extends OWLAxiom>> gens;
//        gens = new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();
//        gens.add(new InferredSubClassAxiomGenerator());
//        gens.add(new InferredClassAssertionAxiomGenerator());
//        gens.add(new InferredEquivalentClassAxiomGenerator());
//        gens.add(new InferredEquivalentObjectPropertyAxiomGenerator());
//        gens.add(new InferredInverseObjectPropertiesAxiomGenerator());
//        gens.add(new InferredSubObjectPropertyAxiomGenerator());
//
//        OWLOntology infOnt = manager.createOntology(URI.create(ontology.getURI() + "_inferred"));
//
//        InferredOntologyGenerator iog = new InferredOntologyGenerator(reasoner, gens);
//        iog.fillOntology(manager, infOnt);        
//        
//        Set<OWLAxiom> inferredAxioms = infOnt.getAxioms();
//        return inferredAxioms;
//	}
	
	//Return string representation of all inferred axioms.
//	public String getInferredAxioms() throws OWLException {
//		reasoner.loadOntologies(Collections.singleton(ontology));
//		reasoner.classify();				
//		List<InferredAxiomGenerator<? extends OWLAxiom>> gens;
//        gens = new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();
//        gens.add(new InferredSubClassAxiomGenerator());
//        gens.add(new InferredClassAssertionAxiomGenerator());
//        gens.add(new InferredEquivalentClassAxiomGenerator());
//        gens.add(new InferredEquivalentObjectPropertyAxiomGenerator());
//        gens.add(new InferredInverseObjectPropertiesAxiomGenerator());
//        gens.add(new InferredSubObjectPropertyAxiomGenerator());
//
//        OWLOntology infOnt = manager.createOntology(URI.create(ontology.getURI() + "_inferred"));
//
//        InferredOntologyGenerator iog = new InferredOntologyGenerator(reasoner, gens);
//        iog.fillOntology(manager, infOnt);        
//        
//        Set<OWLAxiom> inferredAxioms = infOnt.getAxioms();
//        
//        String result = "";
//        result += "Inferred Axioms: "; result += inferredAxioms.size();result += "\n\n";
//		Iterator<OWLAxiom> axiomIterator = inferredAxioms.iterator();
//    	while (axiomIterator.hasNext()){
//    		result += objectRenderer.render(axiomIterator.next(), entityRenderer);
//    		result += "\n";    		
//    	}
//    	result += "\n";		
//    	return result;    	        
//	}
	
	//Returns string representation of all inferred disjoint classes axioms.
//	public String getInferredDisjointAxioms() throws OWLException {
//		reasoner.loadOntologies(Collections.singleton(ontology));
//		reasoner.classify();				
//		List<InferredAxiomGenerator<? extends OWLAxiom>> gens;
//        gens = new ArrayList<InferredAxiomGenerator<? extends OWLAxiom>>();               
//        gens.add(new InferredDisjointClassesAxiomGenerator());
//
//        OWLOntology infOnt = manager.createOntology(URI.create(ontology.getURI() + "_inferred"));
//
//        InferredOntologyGenerator iog = new InferredOntologyGenerator(reasoner, gens);
//        iog.fillOntology(manager, infOnt);        
//        
//        Set<OWLAxiom> inferredAxioms = infOnt.getAxioms();
//        
//        String result = "";
//        result += "Inferred Axioms: "; result += inferredAxioms.size();result += "\n\n";
//		Iterator<OWLAxiom> axiomIterator = inferredAxioms.iterator();
//    	while (axiomIterator.hasNext()){
//    		result += objectRenderer.render(axiomIterator.next(), entityRenderer);
//    		result += "\n";    		
//    	}
//    	result += "\n";		
//    	return result;    	        
//	}
	
	public String printAxiom(OWLAxiom axiom){
		String result = "";
		result += objectRenderer.render(axiom);
		return result;
	}
		
	public String printAxioms(Set<OWLAxiom> axioms){		
		String result = "";
		Iterator<OWLAxiom> it = axioms.iterator();		
		while (it.hasNext()){
			result += printAxiom(it.next());
			result += "\n";
		}		
		return result;
	}
	
	public String printArrAxioms(OWLAxiom[] axioms){
		String result = "";		
		for (int k = 0; k < axioms.length;k++){
			result += printAxiom(axioms[k]);
			result += "\n";
		}				
		return result;
	}
	
	public String printDesc(OWLClassExpression desc){
		String result = "";
		result += objectRenderer.render(desc);
		return result;
	}
	
	public String printDescs(Set<OWLClassExpression> descs){
		String result = "";
		Iterator<OWLClassExpression> it = descs.iterator();		
		while (it.hasNext()){
			result += printDesc(it.next());
			result += "\n";
		}		
		return result;
	}
		
	public String printClass(OWLClass cls){
		String result = "";
		result += objectRenderer.render(cls);
		return result;
	}
	
	public String printClasses(Set<OWLClass> classes){
		String result = "";
		Iterator<OWLClass> it = classes.iterator();		
		while (it.hasNext()){
			result += printClass(it.next());
			result += "\n";
		}		
		return result;
	}
	
	public String printArrAxioms2(OWLAxiom[][] axiomSets){
		String result = "";
		for (int k = 0; k < axiomSets.length;k++){
			result += (k+1) + ".\n";
			result += "-----------------------------------------------------------------------";
			result += "\n";
			result += printArrAxioms(axiomSets[k]);
			result += "\n";
		}
		return result;
	}

}
